<template>
<el-scrollbar class="main-canves my-scrollbar" ref="mainCanves" id="mainCanves">
    <div class="canves-tool">
        <el-tooltip effect="dark" :content="item.name" placement="left" v-for="(item, i) in toolList" :key="i">
            <i id="tools" :style="item.check?'color:#409EFF;':''" :class="`iconfont ${item.icon}`" @click="handleBtns(i, item)"></i>
        </el-tooltip>
    </div>
    <div class="canves-status">
        <span>实验创建于 {{'2019/01/18'}}</span>
        <span class="c-s-status">{{'草稿'}}</span>
    </div>
    <div class="canves-btns">
        <div class="c-f-wrap">
            <div class="c-f-w-item" v-for="(item, i) in editBtns" :key="i">
                <i :class="`iconfont ${item.icon}`"></i>
                <span class="c-f-w-name">{{item.name}}</span>
            </div>
        </div>
    </div>
    <div @contextmenu="$easycm($event,$root,'canves')" @click="$emit('clickCanves')" class="jsplumb-box" id="jsplumbBox" :style="zoomVal" @drop="onDrop" @dragover="onDragover" v-drag="nodes">
        <div @contextmenu.stop="$easycm($event,$root,'canvesDom')" @click.stop="handleClickNode(item)" :id="item.id" class="j-b-item" :style="{left: `${item.x}px`, top: `${item.y}px`}" v-for="(item, i) in itemList" :key="i">
            <i :class="`iconfont ${item.icon}`"></i>
            <span>{{item.name}}</span>
            <i class="iconfont icon-moxingguanli"></i>
        </div>
    </div>
    <easy-cm tag="canves" :itemWidth="180" :itemHeight="32" :itemSize="12" :list="canvesCmList" @ecmcb="handleCanvesCmList" :underline="false" :arrow="true"></easy-cm>
    <easy-cm tag="canvesDom" :itemWidth="180" :itemHeight="32" :itemSize="12" :list="cmList" @ecmcb="handleClickMenu" :underline="false" :arrow="true"></easy-cm>
</el-scrollbar>
</template>

<script>
import { jsPlumb } from 'jsplumb'
import { mapGetters } from 'vuex'
let common = {
    isSource: true,
    isTarget: true,
    maxConnections: -1,
    connector: ['Bezier', { curviness: 30 }],
    Endpoint: ['Dot', { radius: 2 }],
    connectionType: 'basic',
    paintStyle: {
        stroke: '#909399',
        fill: 'transparent',
        radius: 2,
        strokeWidth: 2
    },
    hoverPaintStyle: {
        fill: '#909399',
        stroke: '#909399'
    }
}
export default {
    name: 'MainCanves',
    data () {
        return {
            instance: null,
            nodes: { current: 'jsplumbBox', wrap: 'mainCanves' },
            canvesCmList: [
                { text: '复制选中节点', icon: 'iconfont icon-fuzhi' },
                { text: '粘贴节点', icon: 'iconfont icon-niantiejiedian' },
                { text: '撤销删除的节点', icon: 'iconfont icon-chexiaoshanchudejiedian' },
                { text: '添加注释', icon: 'iconfont icon-tianjiazhushi' },
                { text: '左侧目录中找到实验', icon: 'iconfont icon-dingweimoxing' },
                { text: '左侧目录中找到模型', icon: 'iconfont icon-dingweimoxing' },
                { text: '保存实验副本', icon: 'iconfont icon-baocunshiyanfuben' },
                { text: '查看实验副本', icon: 'iconfont icon-chakanshiyanfuben' }
            ],
            cmList: [
                { text: '重命名', icon: 'iconfont icon-zhongmingming' },
                { text: '删除', icon: 'iconfont icon-shanchu' },
                { text: '复制', icon: 'iconfont icon-fuzhi' },
                { text: '添加注释', icon: 'iconfont icon-tianjiazhushi' },
                { text: '从此处开始执行', icon: 'iconfont icon-congcichukaishizhihang' },
                { text: '执行到此处', icon: 'iconfont icon-zhihangdaocichu' },
                { text: '执行该节点', icon: 'iconfont icon-zhihanggaijiedian' },
                {
                    text: '小数据量试运行',
                    icon: 'iconfont icon-kaishizhihang',
                    children: [
                        { text: '全部执行', icon: 'iconfont icon-kaishizhihang' },
                        { text: '从此处开始执行', icon: 'iconfont icon-congcichukaishizhihang' },
                        { text: '执行到此处', icon: 'iconfont icon-zhihangdaocichu' },
                        { text: '执行该节点', icon: 'iconfont icon-zhihanggaijiedian' }
                    ]
                },
                { text: '查看数据', icon: 'iconfont icon-chakanshuju' },
                {
                    text: '模型选项',
                    icon: 'iconfont icon-moxingxuanxiang',
                    children: [
                        { text: '导出PMML', icon: 'iconfont icon-chakanrizhi' },
                        { text: '查看模型', icon: 'iconfont icon-moxingxuanxiang' },
                        { text: '保存模型', icon: 'iconfont icon-baocunshiyanfuben' },
                        { text: '定位模型', icon: 'iconfont icon-dingweimoxing' }
                    ]
                },
                { text: '查看日志', icon: 'iconfont icon-chakanrizhi' },
                { text: '编辑AutoML参数', icon: 'iconfont icon-bianjicanshu' },
                { text: '调休运行详情', icon: 'iconfont icon-tiaocanyunhangxiangqing' }
            ],
            zoomVal: '',
            scale: 1,
            toolList: [
                {
                    name: '放大',
                    icon: 'icon-fangda'
                },
                {
                    name: '缩小',
                    icon: 'icon-suoxiao'
                },
                {
                    name: '全屏',
                    icon: 'icon-quanping',
                    check: false
                },
                {
                    name: '适应画布',
                    icon: 'icon-shiyinghuabu'
                },
                {
                    name: '实际尺寸',
                    icon: 'icon-shijichicun'
                },
                {
                    name: '框选节点',
                    icon: 'icon-kuangxuanjiedian',
                    check: false
                }
            ],
            editBtns: [
                {
                    name: '运行历史',
                    icon: 'icon-yunhanglishi'
                },
                {
                    name: '保存副本',
                    icon: 'icon-baocunfuben'
                },
                {
                    name: '运行实验',
                    icon: 'icon-yunhangshiyan'
                }
            ],
            itemList: []
        }
    },
    computed: {
        ...mapGetters({
            nodeData: 'experiment/nodeData'
        })
    },
    mounted () {
        this.init()
    },
    methods: {
        // 点击每个节点，触发右侧表单更新
        handleClickNode (item) {
            this.$emit('clickNode', item)
        },
        // 点击每个节点右侧菜单事件
        handleClickMenu (indexList) {
            switch (indexList[0]) {
            case 0:
                console.log('打开')
                this.$emit('addTab', this.contexMenuItem)
                break
            case 1:
                console.log('复制')
                break
            case 2:
                console.log('重命名')
                break
            case 3:
                console.log('删除')
                break
            }
        },
        // 画布右侧菜单事件
        handleCanvesCmList (indexList) {
            switch (indexList[0]) {
            case 0:
                console.log('打开')
                this.$emit('addTab', this.contexMenuItem)
                break
            case 1:
                console.log('复制')
                break
            case 2:
                console.log('重命名')
                break
            case 3:
                console.log('删除')
                break
            }
        },
        // 拖拽到指定区域了，进行的操作
        onDrop (e) {
            e.preventDefault()
            const { name } = this.nodeData
            let x = e.offsetX - 61
            let y = e.offsetY - 14
            let id = Math.random()
            this.itemList.push({
                name,
                icon: 'icon-moxingguanli',
                id: `item-${id}`,
                x,
                y
            })
            this.$nextTick(() => {
                this.setCommonProp(`item-${id}`)
            })
        },
        // 拖拽过程中阻止默认事件
        onDragover (e) {
            e.preventDefault()
        },
        init () {
            jsPlumb.ready(() => {
                // 设置节点共用属性
                this.instance = jsPlumb.getInstance(common)
                this.instance.setContainer('jsplumbBox')
                // 拖动创建的链接，再次拖动时设置不让链接断开
                this.instance.importDefaults({
                    ConnectionsDetachable: false
                })
                let arr = this.itemList
                // 遍历每个节点
                for (let i = 0; i < arr.length; i++) {
                    this.setCommonProp(arr[i].id)
                    // i > 0 && this.instance.connect({
                    //     uuids: [arr[i - 1].id, arr[i].id],
                    //     overlays: [ ['Arrow', { width: 6, length: 6, location: 1 }] ]
                    // })
                }
                this.fitCanves()
            })
        },
        // 设置节点可拖拽、拖拽范围、可连接
        setCommonProp (id) {
            this.instance.draggable(id, {
                containment: 'jsplumbBox'
            })
            const arr = ['RightMiddle', 'LeftMiddle', 'TopCenter', 'BottomCenter']
            for (let i = 0; i < arr.length; i++) {
                this.instance.addEndpoint(id, {
                    anchors: arr[i],
                    uuid: id,
                    overlays: [ ['Arrow', { width: 6, length: 6, location: 1 }] ],
                    connectorOverlays: [
                        ['Arrow', { width: 6, length: 6, location: 1 }]
                    ]
                }, common)
            }
        },
        // 工具栏里各个按钮点击事件
        handleBtns (n, item) {
            switch (n) {
            case 0: // 放大
                this.getZoom(+0.05)
                break
            case 1: // 缩小
                this.getZoom(-0.05)
                break
            case 2: // 全屏
                item.check = !item.check
                this.toolList[5].check = false
                this.$emit('fullScreen')
                break
            case 3: // 适应画布
                this.fitCanves()
                break
            case 4: // 实际尺寸
                this.getZoom(0)
                break
            case 5: // 框选节点
                this.selectDom(item)
                break
            }
        },
        // 框选节点
        selectDom (item) {
            item.check = !item.check
            let box = document.getElementById('jsplumbBox')
            let fileDivs = document.getElementsByClassName('j-b-item')
            // 当框选状态时，移到画布上是十字型
            box.style.cursor = item.check ? 'crosshair' : 'pointer'
            // 移到画布的每个节点上保持手型
            for (let i = 0; i < fileDivs.length; i++) {
                fileDivs[i].style.cursor = 'pointer'
            }
            if (item.check) {
                document.onmousedown = e => {
                    if (e.target.id === 'tools') {
                        box.style.cursor = !item.check ? 'crosshair' : 'pointer'
                        document.onmousedown = null
                    } else {
                        let x = e.clientX
                        let y = e.clientY
                        let div = document.createElement('div')
                        div.className = 'tempDiv'
                        div.style.left = `${x}px`
                        div.style.top = `${y}px`
                        document.body.appendChild(div)
                        document.onmousemove = ev => {
                            div.style.left = `${Math.min(ev.clientX, x)}px`
                            div.style.top = `${Math.min(ev.clientY, y)}px`
                            div.style.width = `${Math.abs(x - ev.clientX)}px`
                            div.style.height = `${Math.abs(y - ev.clientY)}px`
                            document.onmouseup = () => {
                                let selectedEls = []
                                // 获取参数
                                let l = div.offsetLeft
                                let t = div.offsetTop
                                let w = div.offsetWidth
                                let h = div.offsetHeight
                                for (let i = 0; i < fileDivs.length; i++) {
                                    let pos = fileDivs[i].getBoundingClientRect()
                                    let sl = pos.width + pos.x
                                    let st = pos.height + pos.y
                                    if (sl > l && st > t && pos.x < l + w && pos.y < t + h) {
                                        // 该DOM元素被选中，进行处理
                                        selectedEls.push(fileDivs[i])
                                    }
                                }
                                // 打印被选中DOM元素
                                console.log(selectedEls)
                                div.parentNode.removeChild(div)
                                document.onmousemove = null
                                document.onmouseup = null
                            }
                        }
                    }
                }
            }
        },
        // 适应画布
        fitCanves () {
            // this.scale = 1
            let node = this.$refs['mainCanves'].$refs['wrap']
            let canves = document.getElementById('jsplumbBox')
            let nodeS = this.resetCavas()
            let height = document.documentElement.clientHeight
            let width = document.documentElement.clientWidth
            height = (height - 60) / 2
            width = width * 0.6 / 2
            let slitL = 2000 + width
            let slitT = 1000 + height
            if (this.scale !== 1) {
                slitL = (2000 + width) - (this.scale - 1) * 2000
                slitT = (1000 + height) - (this.scale - 1) * 1500
                canves.style.left = '-' + (nodeS.centerLeft - slitL) + 'px'
                canves.style.top = '-' + (nodeS.centerTop - slitT) + 'px'
            } else {
                canves.style.left = '-' + (nodeS.centerLeft - slitL) + 'px'
                canves.style.top = '-' + (nodeS.centerTop - slitT) + 'px'
            }
            node.scrollTop = 1000
            node.scrollLeft = 2000
        },
        resetCavas () {
            let nodeArray = document.getElementsByClassName('j-b-item')
            let leftArray = []
            let topArray = []
            if (nodeArray.length > 0) {
                for (let k = 0; k < nodeArray.length; k++) {
                    leftArray.push(parseInt(nodeArray[k].style.left))
                    topArray.push(parseInt(nodeArray[k].style.top))
                }
            }
            leftArray = leftArray.sort((a, b) => { return a - b })
            topArray = topArray.sort((a, b) => { return a - b })
            let minTop = 0
            let maxTop = 0
            let minLeft = 0
            let maxLeft = 0
            let centerLeft = 0
            let centerTop = 0
            minTop = topArray[0]
            maxTop = topArray[topArray.length - 1]
            minLeft = leftArray[0]
            maxLeft = leftArray[leftArray.length - 1]
            centerLeft = (minLeft + maxLeft) / 2
            centerTop = (minTop + maxTop) / 2
            return {
                centerLeft: centerLeft,
                centerTop: centerTop
            }
        },
        // 放大、缩小功能
        getZoom (num) {
            let n = this.scale + num
            if (num < 0 && n < 0.6) {
                this.$message.warning('您已缩小到极限了')
                n = 0.6
                return false
            }
            if (num > 0 && n > 1.8) {
                n = 1.7
                this.$message.warning('您已放大到极限了')
                return false
            }
            this.zoomVal = {
                '-webkit-transform': `scale(${n})`,
                '-moz-transform': `scale(${n})`,
                '-ms-transform': `scale(${n})`,
                '-o-transform': `scale(${n})`,
                'transform': `scale(${n})`
            }
            this.instance.setZoom(n)
            this.scale = n
        }
    }
}
</script>

<style lang="less">
.main-canves {
    position: relative;
    height: 100%;
    width: 100%;
    .jsplumb-box {
        width: 8000px;
        height: 4000px;
        left: -4000px;
        top: -2000px;
        background: #ffffff;
        position: relative;
        cursor: pointer;

        .j-b-item {
            background: #ffffff;
            position: absolute;
            width: 120px;
            height: 26px;
            border: 1px solid #409EFF;
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: space-around;
            left: 0;
            top: 0;
            i {
                font-size: 16px;
            }
            span {
                font-size: 12px;
            }
        }

        .j-b-item:hover {
            background: rgba(227,244,255,.9);
        }
    }

    .canves-btns {
        position: absolute;
        top: 0px;
        left: 0;
        z-index: 1;
        background: #ffffff;
    }

    .c-f-wrap {
        display: flex;

        i {
            font-size: 18px;
            margin-right: 5px;
        }

        .c-f-w-item {
            cursor: pointer;
            padding: 0 10px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .c-f-w-name {
            font-size: 12px;
        }

        .c-f-w-item:hover {

            i,
            .c-f-w-name {
                color: #409EFF;
            }
        }
    }

    .canves-status {
        position: absolute;
        top: 0;
        right: 0;
        background: #ffffff;
        z-index: 1;
        span {
            text-align: right;
            font-size: 14px;
            padding: 0 15px;
        }
    }
    .canves-tool {
        background: #ffffff;
        position: absolute;
        padding-right: 15px;
        top: 24px;
        right: 0;
        z-index: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex-direction: column;
        height: 200px;

        i {
            font-size: 18px;
            cursor: pointer;
        }

        i:hover {
            color: #409EFF;
        }
    }
}
</style>
